// Mrjones_GPU_ButtView.h : interface of the CMrjones_GPU_ButtView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MRJONES_GPU_BUTTVIEW_H__E1F7DDD5_D6D0_44C2_AD87_AF7E31E1F667__INCLUDED_)
#define AFX_MRJONES_GPU_BUTTVIEW_H__E1F7DDD5_D6D0_44C2_AD87_AF7E31E1F667__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


#define RealTimeEvent_Flowing  100
#define RealTimeEvent_ShowImage 101
#define	RealTimeEvent_Animation	1
#define	ANIMATE_RATE	2


enum MOUSE_LEFT_BUTTON_ACTION {
	CIRCLE_CAMERA=0,AUTO_CIRCLE_CAMERA_X,AUTO_CIRCLE_CAMERA_Y,AUTO_CIRCLE_CAMERA_Z, 
	PICK_OBJECT
};
enum MOUSE_RIGHT_BUTTON_ACTION {
	ZOOM_CAMERA=0
};
enum MOUSE_MIDDLE_BUTTON_ACTION {
	TRANSLATE_CAMERA = 0
};

enum PICK_OBJECT_TYPE {
	NoPicking=0, Points,Faces,Edges,
	PointsAndLines,PointsAndFaces,FacesAndLines,
	SkeletonJoints,SkeletonBones,Cube
};

class   CMySplitterWnd;
class	COptionFormView;
class	CLego_3Ddoc;
class	fipWinImage;
class	Image_Resize;
class	CDLG_ImgResizer_SpecifySize;
class   CDLG_2DSpline_Setting;
class	CDLG_Rotate_Skeleton;
class	CDLG_CameraSetting;
class	CDLG_CubeAnalyzer;
class	Arrow3D;
class	GLFont;
class	CTexture;
class	CPseudoColorRGB;
class	Vector2;
class	Vector3;
class	Matrix3;	
enum DrawHostColor;
enum HandleMode;

using std::auto_ptr;

template<class T> class CTrackBall;

class CamSet{
public:
	CTrackBall<double> * TB;
	GLfloat*	pZoom;
	GLfloat*	pMove;
	CamSet();
 	void create(CWnd* pWnd, CSize WindowSize, int RTE_MODE = RealTimeEvent_Animation);
	~CamSet();
};

class	CLego_3Dview : public CView
{
protected: // create from serialization only
	CLego_3Dview();
	DECLARE_DYNCREATE(CLego_3Dview)
//data contents
	//for frame
	COptionFormView *pOptFormView;
	HDC hMemDC; 
	HINSTANCE	m_hInstance;
	HACCEL		m_hAccelerator; 
public:	
	//View Window 
	CSize WindowSize;
	GLdouble aspect;
	//for mouse
	std::vector<CPoint> Warp_SrcP, Warp_DstP; //image warping
	MOUSE_LEFT_BUTTON_ACTION MouseLBtnAction; //mouse left button action
	MOUSE_MIDDLE_BUTTON_ACTION MouseMBtnAction; //mouse middle button action
	MOUSE_RIGHT_BUTTON_ACTION MouseRBtnAction; //mouse right button action
	CPoint LeftDownPos,RightDownPos,middleDownPos;
	CPoint LeftUpPos,RightUpPos,middleUpPos;
	bool bLeftButtonDown,bMiddleButtonDown,bRighButtonDown;
	CPoint m_OldMousePoint;
	PICK_OBJECT_TYPE PickObjType;	//pick object type
	bool bPickByRect;
	CPoint m_PickingRectStart,m_PickingRectEnd;
	bool bAntiPick, bMultiPick;
	int	 pickedVidx,pickedFidx,pickedEidx, pickedSkeletonJointIdx, pickedSkeletonBoneIdx, pickedCubeIdx; 
	int  npickedV,npickedF,npickedE, npickedSkeletonJoint,npickedSkeletonBone;// total number of picked objects
	const float PICK_RANGE_EPSILON;
	CString m_PickObjectInfoString;	
	bool bPickFrontOnly,bPickSilhouetteOnly;
	float fPickViewOscLow, fPickViewOscHigh;
	float fPickViewFrontLow; 
	// different cursor shapes
	HCURSOR		m_hcArrow;
	HCURSOR		m_hcCross;
	HCURSOR		m_hcTrans;
	HCURSOR		m_hcHoriz;
	HCURSOR		m_hcVerti;
	HCURSOR		m_hcNWSE;
	HCURSOR		m_hcNESW;
	HCURSOR		m_hcRotate;
	//for GL
	float	fGLViewWidth, fGLViewHeight, fGLViewNear, fGLViewFar;
	int GLPixelIndex;
	HGLRC hGLContext;
	float *pActiveCamMove, *pActiveCamZoom;
	CTrackBall<double>	*m_pTrackBall;
	std::vector<CamSet> m_CamSets;
	bool bCullBackFace;
	float fBackColor[3]; 
	float	fLightAmbient[4],  fLightDiffuse[4],
			fLightSpecular[4], fLightPosition[4], 
			fLightShininess;
	float	fMatAmbientFront[4],  fMatAmbientBack[4],
			fMatDiffuseFront[4],  fMatDiffuseBack[4],
			fMatSpecularFront[4], fMatSpecularBack[4],
			fMatEmissionFront[4], fMatEmissionBack[4],
			fMatShininess, fMatTransparency;
	CTexture			*pParamTexture;			//sample for texture mapping
	CTexture			*pFittingImgTexture;	//sample for fitting texture mapping
	CPseudoColorRGB		*PseudoColor;
	bool bTransparent,bSmoothShading,bUseNormal,bShowTexture;
	bool bOrthoProj;
	bool bDrawFaceAndLine;
	float m_Cam_Angle;
	float m_light2_Angle,	m_light2_Dist,
		  m_fSpeedCamMove,	m_fSpeedCamZoom;
	float fGLBkgZcoord;
	Vector2 *fBkgTexcoordBound;
	GLuint DisplayList_2d;
	bool bShowAxes;
	bool bShowBoundingBox;
	bool bShowBKG;
	bool bShowVertexColor;
	auto_ptr<GLFont> pFont;
	Arrow3D *m_pArrow3D;
	bool m_bDrawSpacePar;
	//for dialog	
	CDLG_ImgResizer_SpecifySize *m_pDlgImgResizerSpeciSize;
	CDLG_2DSpline_Setting	*m_pDlg2DSplineSetting; 
	CDLG_CameraSetting		*m_pDlgCamSetting;
	CDLG_CubeAnalyzer		*m_pDlgCubeAnalyzer;
	//for image resizing and warping
	fipWinImage *pFipWinImage;
	const Image_Resize *pImage;
	bool bShowImage, bShowGrid; 
	int imgWidth,imgHeight;
	//for fluid
	bool bIsFlowing;
	UINT FrameIntervalTime;
	//for parametrization
	bool bParameterized;
	//for spline on image
		/* for mouse interactive, dragging...*/
	CPoint		m_PointOld;		// the old point of mouse move
	CPoint		m_PointOrigin;	// point when mouse first click
	CPoint      m_MousePos;
	bool		m_bDragging ;	// if it dragging
	bool		m_bRubber;		// dragging a rubber band
	bool		m_bShowSpline,	m_bShowSplineCurve, m_bShowSplineVertex, 	m_bShowSplineVertexIndex,
				m_bShowSplineNormal	,m_bColoredLines;
	bool		m_bShowSplineInMeshView;
	//contour matching 
	bool		bShowLinkage, bShow3DPairs;
	bool		bShowCandidateVertex;
	bool		bShowMatchedVertex;
	//Skeleton 
	bool bShowSkeleton, bShowSkltJointsName, bShowSkltBonesName, bShowBodyPart, bShowPartCut;
	//Image warping based on triangulation
	bool bShowSilProj, bShowWarpPairs;
	bool bShowWarpMesh;
	Vector2 *m_SideImgPosOffset;
// Operations	
	// Attributes
public:
	CLego_3Ddoc* GetDocument();
	virtual ~CLego_3Dview();
	virtual void OnDraw(CDC* dc); 
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
public:
	void SetOptionFormView(COptionFormView *pFormView) {pOptFormView = pFormView;}
	COptionFormView* GetOptionFormView(void) {return pOptFormView;}
	//for mouse
	void GetPickSPDir(int px, int py, Vector3 &sp, Vector3 &dir);
	void DrawPickingRect();
	void PickByClick(CPoint p);
	void PickByRect(CPoint starp, CPoint endp);
	//for GL
	BOOL SetWindowPixelFormat(HDC hDC);
	void InitOpenGLWithMemoryDC(CDC *pDC);
	BOOL CreateViewGLContext(HDC hDC=NULL);
	void SetRenderingContext(HDC hDC=NULL);
	void Build2DSceneList(void);
	void Init3DCamera(void);
	void UpdateMatTransparency(GLclampf fTransparency);
	void UpdateRenderViewSize(int cx, int cy);
	//for image
	BOOL IsPinsideImg(CPoint point);
	//for spline on image
	void DrawNewPolygon(CDC *pDC);
	void DrawNewSpline(CDC *pDC);
	void SetCursorByMode( HandleMode mode );
	void DisplayBkgPlane();

//message map
protected:
	DECLARE_MESSAGE_MAP()
public:
	
	virtual void OnUpdate(CView *pSender, LPARAM lHint, CObject *pHint);
	virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
	afx_msg void OnOpenresult();
	afx_msg int	 OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDestroy();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg BOOL OnEraseBkgnd(CDC*);
	afx_msg void OnPaint();
	afx_msg void OnTimer(UINT nIDEvent);	
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg	BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg BOOL PreTranslateMessage(MSG* pMsg);
	afx_msg void OnImageShowGrid();
	afx_msg void OnUpdateImageShowGrid(CCmdUI* pCmdUI);
	afx_msg void OnCameraCircle();				//mesh
	afx_msg void OnUpdateCameraCircle(CCmdUI *pCmdUI);
	afx_msg void OnShowAxes();
	afx_msg void OnUpdateShowAxes(CCmdUI *pCmdUI);
	afx_msg void OnShowBBox();
	afx_msg void OnUpdateShowBBox(CCmdUI *pCmdUI);
	afx_msg	void OnShowBKG();
	afx_msg void OnUpdateShowBKG(CCmdUI *pCmdUI);
	afx_msg void OnCameraAutoInertiaCircle();
	afx_msg void OnUpdateCameraAutoInertiaCircle(CCmdUI *pCmdUI);
	afx_msg void OnCameraAutoCircleX();
	afx_msg void OnCameraAutoCircleY();
	afx_msg void OnCameraAutoCircleZ();
	afx_msg void OnUpdateCameraAutoCircleX(CCmdUI *pCmdUI);
	afx_msg void OnUpdateCameraAutoCircleY(CCmdUI *pCmdUI);
	afx_msg void OnUpdateCameraAutoCircleZ(CCmdUI *pCmdUI);
	void GetGLViewData(Matrix3 &rotaion, GLdouble *const modelview=NULL, GLdouble * const projection=NULL, GLint *viewport=NULL);
	bool bCamCircle;
	unsigned m_CirlModelIdx;	
	void SwitchCamCirclingObj();
};

inline void GETRGBFROMREF(float* const color, const COLORREF colorRef)
{
	color[0]  = (float)GetRValue(colorRef) / 255.0f;
	color[1]  = (float)GetGValue(colorRef) / 255.0f;
	color[2]  = (float)GetBValue(colorRef) / 255.0f;
}


#ifndef _DEBUG  // debug version in Mrjones_GPU_ButtView.cpp
inline CLego_3Ddoc* CLego_3Dview::GetDocument() 
{  return (CLego_3Ddoc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MRJONES_GPU_BUTTVIEW_H__E1F7DDD5_D6D0_44C2_AD87_AF7E31E1F667__INCLUDED_)
